Skip to main content

第25章 字符串与字符数组

在程序设计中,字符串是由字符组成的序列,常用于表示文本信息。在C语言中,字符串通过字符数组实现;而C++语言中,除字符数组外,还提供string类简化字符串操作。

25.1 字符数组与字符串基础概念

25.1.1 字符数组

存储字符类型的数组,可存储任意字符,不一定带结束符\0,不属于字符串。 示例:

char arr[3] = {'A','B','C'}; // 纯字符数组,无'\0',不是字符串

25.1.2 字符串

以空字符\0(ASCII值0)作为结束标记的字符序列,必须存储在字符数组中。

char str1[6] = {'H','e','l','l','o','\0'};
char str2[] = "World"; // 编译器自动末尾追加'\0'

25.2 字符数组定义与初始化

25.2.1 逐个字符初始化

手动填写每个字符,可手动添加\0转为字符串:

char c1[6] = {'C','h','i','n','a','\0'}; // 合法字符串
char c2[3] = {'a','b','c'}; // 仅字符数组,无结束符

25.2.2 字符串常量初始化

直接使用双引号字符串,编译器自动补充\0

char s1[] = "Hello"; // 数组长度6:H e l l o \0
char s2[10] = "Hi"; // 前两字符H i,剩余全部填充'\0'

25.3 字符串输入输出

25.3.1 C语言风格(printf / scanf / puts / gets)

头文件:<stdio.h>

  1. printf / puts 输出
char str[] = "Hello World";
printf("%s\n", str); // %s读到'\0'停止
puts(str); // 自动换行,无需格式符
  1. scanf 输入:遇到空格、换行停止
char input[20];
scanf("%s", input);
  1. gets:读取带空格字符串,C11标准已废弃,存在缓冲区溢出安全漏洞。

25.3.2 C++ cin / cout

#include <iostream>
using namespace std;
char input[20];
cin >> input; // 空格截断
cout << input << endl;

25.3.3 cin.getline 读取整行(含空格)

char line[50];
cin.getline(line, 50); // 最多读取49字符,自动补'\0'

25.4 C字符串标准库函数(头文件<cstring>

25.4.1 strlen 获取字符串长度

功能:统计有效字符,不包含\0

char s[] = "Hello";
int len = strlen(s); // len = 5

25.4.2 strcpy 字符串复制

将源字符串完整复制到目标数组(含\0),目标数组空间必须充足:

char dest[20];
char src[] = "Copy me";
strcpy(dest, src);

25.4.3 strcat 字符串拼接

把源字符串追加到目标末尾,覆盖原\0,末尾重新添加结束符:

char dest[20] = "Hello";
char src[] = " World";
strcat(dest, src); // dest = "Hello World"

25.4.4 strcmp 字符串比较

按ASCII码逐字符对比:

  • s1 > s2:返回正数
  • s1 == s2:返回0
  • s1 < s2:返回负数
int res1 = strcmp("apple", "banana"); // 负数
int res2 = strcmp("hello", "hello"); // 0

25.4.5 strncmp 限定长度比较

仅对比前n个字符:

int res = strncmp("abcde", "abcfg", 3); // 前3位相等,返回0

25.5 C++ string 类(头文件<string>

25.5.1 string 对象初始化

string s1; // 空字符串
string s2 = "Hello";
string s3(s2); // 拷贝s2
string s4(5, 'A'); // 5个'A':"AAAAA"

25.5.2 常用成员与运算符

  1. 长度:s.length() / s.size()
  2. 判断空:s.empty()
  3. 拼接:+ / +=
string a = "Hi", b = " C++";
string c = a + b;
a += b;
  1. 字符访问:s[下标] / s.at(下标)(at会越界检查)
  2. 直接比较:== < > 运算符重载
  3. 查找子串 .find(子串),未找到返回string::npos
string s = "Hello World";
size_t pos = s.find("World"); // pos = 6
  1. 字符串替换 .replace(起始, 长度, 新串)

25.6 char数组与string相互转换

string转C风格字符指针:.c_str()

string s = "Test";
const char* p = s.c_str();

25.7 使用注意事项

  1. C字符串必须以\0结尾,库函数依赖结束符,缺失会乱码;
  2. strcpy、strcat必须保证目标数组容量足够,否则数组越界;
  3. gets函数禁用,优先使用cin.getline / fgets;
  4. string更安全,无需手动管理缓冲区,竞赛推荐优先使用;
  5. getline读取前若有cin遗留换行,需清空缓冲区。